/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.logiclander.ricemine.services.identity;

import com.logiclander.ricemine.utils.LdapUtilities;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.kuali.rice.kim.bo.entity.dto.KimPrincipalInfo;

import org.springframework.ldap.core.ContextMapper;
import org.springframework.ldap.core.DirContextAdapter;

/**
 *
 * @author tcarroll
 */
public class LdapKimPrincipalInfoMapper implements ContextMapper {

  private String principalIdAttributeName = null;
  private String principalNameAttributeName = null;
  private String entityIdAttributeName = null;
  private final Log log = LogFactory.getLog(getClass());

//beg: methods required by ContextMapper interface
  public Object mapFromContext(Object ctx) {
    validateConfiguration();
    KimPrincipalInfo kpi = new KimPrincipalInfo();
    try {
      DirContextAdapter context = (DirContextAdapter) ctx;

      // potential to be special or synthetic, so do some special processing
      if (context.getStringAttribute(principalIdAttributeName).equalsIgnoreCase("dn")) {
        kpi.setPrincipalId(LdapUtilities.buildDn(context, true));
      } else if (context.getStringAttribute(principalIdAttributeName).equals("objectGUID")) {
        kpi.setPrincipalId(LdapUtilities.buildGuid(context));
      } else {
        kpi.setPrincipalId((String) context.getStringAttribute(principalIdAttributeName));
      }

      // potential to be special or synthetic, so do some special processing
      if (context.getStringAttribute(entityIdAttributeName).equalsIgnoreCase("dn")) {
        kpi.setEntityId(LdapUtilities.buildDn(context, true));
      } else if (context.getStringAttribute(entityIdAttributeName).equals("objectGUID")) {
        kpi.setEntityId(LdapUtilities.buildGuid(context));
      } else {
        kpi.setEntityId((String) context.getStringAttribute(entityIdAttributeName));
      }

      kpi.setPrincipalName((String) context.getStringAttribute(principalNameAttributeName));
      kpi.setActive(true); // is there an ldap attribute for this?
      
    } catch (Throwable t) {
      log.error("Error in KimPrincipalContextMapper", t);
      String msg = "KimPrincipalContextMapper failed to create a LdapRecord from the specified Context: " + ctx;
      throw new RuntimeException(msg, t);
    }
    if (log.isDebugEnabled()) {
      log.debug("mapped principal: principalId=" + kpi.getPrincipalId()
              + ", principalName=" + kpi.getPrincipalName()
              + ", entityId=" + kpi.getEntityId()
              + ", isActive=" + kpi.isActive());
    }
    return kpi;
  }

//end: methods required by ContextMapper interface
//beg: helper methods
  public String getPrincipalIdAttributeName() {
    return this.principalIdAttributeName;
  }

  public void setPrincipalIdAttributeName(String attrName) {
    this.principalIdAttributeName = attrName;
  }

  public String getPrincipalNameAttributeName() {
    return this.principalNameAttributeName;
  }

  public void setPrincipalNameAttributeName(String attrName) {
    this.principalNameAttributeName = attrName;
  }

  public String getEntityIdAttributeName() {
    return this.entityIdAttributeName;
  }

  public void setEntityIdAttributeName(String attrName) {
    this.entityIdAttributeName = attrName;
  }

  private void validateConfiguration() {
    if (principalIdAttributeName == null) {
      String msg = "The property 'principalIdAttributeName' must be set.";
      throw new IllegalStateException(msg);
    }
    if (principalNameAttributeName == null) {
      String msg = "The property 'principalNameAttributeName' must be set.";
      throw new IllegalStateException(msg);
    }
    if (entityIdAttributeName == null) {
      String msg = "The property 'entityIdAttributeName' must be set.";
      throw new IllegalStateException(msg);
    }
  }
//end: helper methods
}
